/**
 ******************************************************************************
 * @file    bsp_uart_diver.c
 * @author  陈泳行
 * @date    2025/6/16
 * @version v1.0
 * @brief   UART串口驱动实现文件，提供串口初始化、发送等接口
 ******************************************************************************
 */
#include "bsp_uart_diver.h"

typedef struct
{
	USART_TypeDef 	   *uartx;
	CircularBuffer_t   *cb;
}Usart_t;

Usart_t g_usart_handle[UART_MAX] = {
	[1] = USART1,
	[2] = USART2,
	[3] = USART3,
	[4] = UART4,
	[6] = USART6,
};

/**
 * @brief  串口1中断处理
 * @param  无
 * @return 无
 */
void ore_error(uint8_t uartx)
{
	if((g_usart_handle[uartx].uartx->SR&USART_SR_ORE)!=RESET)
	{
		g_usart_handle[uartx].uartx->SR;//依次读取状态顺序清空标志位
		g_usart_handle[uartx].uartx->DR;//依次读取状态顺序清空标志位
	}		
}


/**
 * @brief  串口单字节发送
 * @param  uartx 串口号
 * 		   data  数据
 * @return 2 没有串口句柄
 * 		    1 超时 
 *		    0 发送成功
 */
char uart_send_byte(uint8_t uartx, uint8_t data)
{
	USART_TypeDef *USARTx = g_usart_handle[uartx].uartx;
	if(USARTx == NULL)return 2;
	uint16_t time = 0xFFFF;
	while((USARTx->SR&UART_FLAG_TXE)==0&&--time)
		if(!time)return 1;
	USARTx->DR = data;
	return 0;
}

/**
 * @brief  串口字符串发送
 * @param  uartx 串口号
 * 		   data  数据
 * @return  1 发送失败
 *		    0 发送成功
 */
char uart_send_str(uint8_t uartx, const char* str)
{
	while(*str)
	{
		if(*str == '\n')
			uart_send_byte(uartx, '\r');
		if(0 == uart_send_byte(uartx, (uint8_t)*str))
			str++;
		else
			return 1;
	}
	return 0;
}

/**
 * @brief  数据流发送
 * @param  uartx 串口号
 * 		   data  数据
 *         len   长度
 * @return  1 发送失败
 *		    0 发送成功
 */
char uart_send_data(uint8_t uartx, uint8_t* data, uint16_t len)
{
	while(len--)
	{
		if(0 == uart_send_byte(uartx, (uint8_t)*data))
			data++;
		else
			return 1;
	}
	return 0;
}

/**
 * @brief  串口重复检测
 * @param  num 串口号
 * @return false：未使用 
 *		   true： 重复利用
 */
bool uart_used(uint8_t num)
{
	static uint8_t uart_num[6] = {0};
	if(uart_num[num] == 1)
	{
#ifdef DEBUG_UART_DRIVER
		printf("发现串口%u重复利用 tick [%d]\n",
										   num,
								HAL_GetTick());
#endif
		return true;
	}
	uart_num[num] = 1;
	return false;
}

/**
 * @brief  串口初始化
 * @param  uartx 串口号
 * 		   cb    环形缓冲区
 * @return 串口初始化状态
 */
UART_ERROR uart_init(uint8_t uartx, void *cb)
{
	if(uartx > UART_MAX - 1) return UART_NOUART;
	if(uart_used(uartx - 1)) return UART_USED;
	if(cb == NULL) return UART_OTHER;

	CircularBuffer_t *cbuff = (CircularBuffer_t *)cb;
	g_usart_handle[uartx].cb = cbuff;

	switch(uartx)
	{
		case 1:
			MX_USART1_UART_Init();
			HAL_UARTEx_ReceiveToIdle_DMA(&huart1, cbuff->buffer, cbuff->size);
//			__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_TC);
		break;
		case 2:
			
		break;
		case 3:
			
		break;
		case 4:
			
		break;
		case 6:
			
		break;
	}
#ifdef DEBUG_UART_DRIVER
	my_printf(&huart1, "USART%d success tick [%d]\n", uartx, HAL_GetTick());
#endif
	return UART_NOERROR;
}
int my_printf(UART_HandleTypeDef *huart, const char *format, ...)
{
	char buffer[512]; // 临时存储格式化后的字符串
	va_list arg;	  // 处理可变参数
	int len;		  // 最终字符串长度
	
	va_start(arg, format);
	// 安全地格式化字符串到buffer
	len = vsnprintf(buffer, sizeof(buffer), format, arg);
	va_end(arg);
	
	// 通过HAL库发送buffer中的内容
	HAL_UART_Transmit(huart, (uint8_t *)buffer, (uint16_t)len, 0xFF);
	return len;
}

